package org.unit.testmgmt.ui.table;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxViewerCellEditor;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.swt.SWT;

/**
 * The table viewer column. 
 * 
 * @author Robert Streng
 *
 */
public class TableViewerColumn {
	public static enum Columntype {
		STRING, INTEGER, DOUBLE, BOOLEAN, OBJECT
	}

	private Set<ITableViewerColumnListener> columnListeners = new HashSet<ITableViewerColumnListener>();

	private Columntype type;
	private int columnIndex = -1;
	private String name;
	private int style = SWT.NONE;
	private int width = -1; // default pack()

	private boolean isCombobox = false;
	private Set<ComboboxEntry> comboboxEntries;
	private Set<ComboboxEntry> cboBooleanEntries = null;

	private CellEditor cellEditor;

	/**
	 * @param name
	 */
	public TableViewerColumn(String name) {
		this(name, SWT.NONE, Columntype.STRING);
	}

	/**
	 * @param name
	 * @param style
	 */
	public TableViewerColumn(String name, int style) {
		this(name, style, Columntype.STRING);
	}

	/**
	 * @param name
	 * @param style
	 * @param type
	 */
	public TableViewerColumn(String name, int style, Columntype type) {
		this(name, style, type, null);
	}

	/**
	 * @param name
	 * @param style
	 * @param type
	 * @param comboboxEntries
	 */
	public TableViewerColumn(String name, int style, Columntype type,
			Set<ComboboxEntry> comboboxEntries) {
		if (comboboxEntries != null || type == Columntype.BOOLEAN) {
			isCombobox = true;

			if (comboboxEntries == null) {
				comboboxEntries = getComboBooleanValues();
			}

			setComboboxEntries(comboboxEntries);
		}

		this.name = name;
		this.comboboxEntries = comboboxEntries;
		this.type = type;
		this.style = style;
	}

	/**
	 * @param comboboxValues 
	 * @return set with combobox entries
	 */
	public static Set<ComboboxEntry> createComboboxSet(String[] comboboxValues) {
		Set<ComboboxEntry> comboboxEntries = new HashSet<ComboboxEntry>(
				comboboxValues.length);
		ComboboxEntry entry;
		for (int i = 0; i < comboboxValues.length; i++) {
			entry = new ComboboxEntry();
			entry.setKey(i);
			entry.setLabel(comboboxValues[i]);
			entry.setValue(comboboxValues[i]);
			comboboxEntries.add(entry);
		}

		return comboboxEntries;
	}

	/**
	 * @return combobox boolean values
	 */
	private Set<ComboboxEntry> getComboBooleanValues() {
		if (cboBooleanEntries == null) {
			cboBooleanEntries = new HashSet<ComboboxEntry>();

			ComboboxEntry entry;

			entry = new ComboboxEntry();
			entry.setKey(0);
			entry.setLabel("false");
			entry.setValue(false);

			cboBooleanEntries.add(entry);

			entry = new ComboboxEntry();
			entry.setKey(1);
			entry.setLabel("true");
			entry.setValue(true);

			cboBooleanEntries.add(entry);
		}

		return cboBooleanEntries;
	}

	/**
	 * @return ComboboxValues
	 */
	public String[] getComboboxLabels() {
		if (comboboxEntries == null) {
			return new String[0];
		}

		String[] comboboxLabels = new String[comboboxEntries.size()];

		Iterator<ComboboxEntry> keySet = comboboxEntries.iterator();

		int i = 0;
		while (keySet.hasNext()) {
			comboboxLabels[i++] = keySet.next().getLabel();
		}

		return comboboxLabels;
	}

	/**
	 * @return combobox entries
	 */
	public Set<ComboboxEntry> getComboboxEntries() {
		return comboboxEntries;
	}

	/**
	 * @param columnIndex
	 */
	public void setIndex(int columnIndex) {
		this.columnIndex = columnIndex;
	}

	public Columntype getType() {
		return type;
	}

	public int getColumnIndex() {
		return columnIndex;
	}

	public boolean isCombobox() {
		return isCombobox;
	}

	public String getName() {
		return name;
	}

	public int getStyle() {
		return style;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public void addChangeListener(ITableViewerColumnListener listener) {
		columnListeners.add(listener);
	}

	public void removeChangeListener(ITableViewerColumnListener listener) {
		columnListeners.remove(listener);
	}

	public Set<ITableViewerColumnListener> getChangeListener() {
		return columnListeners;
	}

	private void setComboboxEntries(Set<ComboboxEntry> comboboxEntries) {
		if (this.cellEditor instanceof ComboBoxViewerCellEditor) {
			ComboViewer viewer = ((ComboBoxViewerCellEditor) cellEditor)
					.getViewer();
			for (ComboboxEntry entry : comboboxEntries)
				viewer.add(entry);
		}

		this.isCombobox = true;
		this.comboboxEntries = comboboxEntries;
	}

	/**
	 * @param cellEditor
	 */
	public void setEditor(CellEditor cellEditor) {
		this.cellEditor = cellEditor;

		if (this.cellEditor instanceof ComboBoxViewerCellEditor) {
			for (ComboboxEntry entry : comboboxEntries)
				((ComboBoxViewerCellEditor) cellEditor).getViewer().add(entry);
		}
	}

}
